local extension = Package:new("qun")
extension.extensionName = "klxf"
-- extension.game_modes_whitelist = { 'kl_heg_mode' }

local H = require "packages/klxf/util"
local U = require "packages/utility/utility"

Fk:loadTranslationTable {
  ["qun"] = "群",
}

local yuanshao = General(extension, "kl__yuanshao", "qun", 4)
local kl__luanji = fk.CreateViewAsSkill {
  name = "kl__luanji",
  anim_type = "offensive",
  pattern = "archery_attack",
  prompt = "#kl__luanji",
  handly_pile = true,
  card_filter = function(self, to_select, selected)
    if #selected == 1 then
      return table.contains(Self:getHandlyIds(), to_select) and
          Fk:getCardById(to_select).suit == Fk:getCardById(selected[1]).suit
    elseif #selected == 2 then
      return false
    end
    return table.contains(Self:getHandlyIds(), to_select)
  end,
  view_as = function(self, cards)
    if #cards ~= 2 then
      return nil
    end
    local c = Fk:cloneCard("archery_attack")
    c.skillName = self.name
    c:addSubcards(cards)
    return c
  end,
}
local kl__xueyi = fk.CreateMaxCardsSkill {
  name = "kl__xueyi",
  correct_func = function(self, player)
    if player:hasSkill(self) then
      local hmax = 0
      for _, p in ipairs(Fk:currentRoom().alive_players) do
        if H.compareKingdomWith(player, p) then
          hmax = hmax + 1
        end
      end
      return hmax
    else
      return 0
    end
  end,
}
yuanshao:addSkill(kl__luanji)
yuanshao:addSkill(kl__xueyi)
Fk:loadTranslationTable {
  ["kl__yuanshao"] = "袁绍",
  ["#kl__yuanshao"] = "高贵的名门",
  ["designer:kl__yuanshao"] = "官方&抗绿先锋",

  ["kl__luanji"] = "乱击",
  [":kl__luanji"] = "出牌阶段，你可将两张相同花色的手牌当【万箭齐发】使用。",
  ["#kl__luanji"] = "乱击:你可将两张相同花色的手牌当【万箭齐发】使用",
  ["kl__xueyi"] = "血裔",
  [":kl__xueyi"] = "锁定技，你的手牌上限+X（X为与你势力相同的角色数）。",

  ["$kl__luanji1"] = "弓箭手，准备放箭！",
  ["$kl__luanji2"] = "全都去死吧！",
  ["~kl__yuanshao"] = "老天不助我袁家啊！……",
}
----------------------------------------------------------------------------
local huaxiong = General(extension, "kl__huaxiong", "qun", 4)
local kl__yaowu = fk.CreateTriggerSkill {
  name = "kl__yaowu",
  mute = true,
  anim_type = "negative",
  frequency = Skill.Compulsory,
  events = { fk.DamageInflicted, fk.GeneralRevealed },
  can_trigger = function(self, event, target, player, data)
    if target ~= player or not player:hasSkill(self) then return false end
    if event == fk.GeneralRevealed then
      if player:usedSkillTimes(self.name, Player.HistoryGame) == 0 then
        for _, v in pairs(data) do
          if table.contains(Fk.generals[v]:getSkillNameList(), self.name) then return true end
        end
      end
    else
      return target == player and data.card
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.GeneralRevealed then
      room:changeMaxHp(player, 2)
      room:recover {
        who = player,
        num = 2,
        skillName = self.name
      }
    else
      if data.card.color ~= Card.Red then
        player.room:notifySkillInvoked(player, self.name, "masochism")
        player:broadcastSkillInvoke(self.name, 1)
        player:drawCards(1, self.name)
      else
        if data.from and not data.from.dead then
          player.room:notifySkillInvoked(player, self.name, "negative")
          player:broadcastSkillInvoke(self.name, 2)
          data.from:drawCards(1, self.name)
        end
      end
    end
  end,
}
local kl__shizhan = fk.CreateActiveSkill {
  name = "kl__shizhan",
  anim_type = "offensive",
  prompt = "#kl__shizhan-active",
  times = function(self)
    return Self.phase == Player.Play and 2 - Self:usedSkillTimes(self.name, Player.HistoryPhase) or -1
  end,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) < 2
  end,
  card_filter = Util.FalseFunc,
  target_filter = function(self, to_select, selected)
    return #selected == 0 and to_select ~= Self.id
        and not Fk:currentRoom():getPlayerById(to_select):isProhibited(Self, Fk:cloneCard("duel"))
  end,
  target_num = 1,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local target = room:getPlayerById(effect.tos[1])
    room:useVirtualCard("duel", nil, target, player, self.name, true)
  end,
}
huaxiong:addSkill(kl__yaowu)
huaxiong:addSkill(kl__shizhan)
Fk:loadTranslationTable {
  ["kl__huaxiong"] = "华雄",
  ["#kl__huaxiong"] = "飞扬跋扈",
  ["designer:kl__huaxiong"] = "官方",

  ["kl__yaowu"] = "耀武",
  [":kl__yaowu"] = "锁定技，当你受到牌造成的伤害时，若此牌：为红色，伤害来源摸一张牌；不为红色，你摸一张牌；当你首次明置赐武将牌后，你增加2点体力上限，回复2点体力。",
  ["kl__shizhan"] = "势斩",
  [":kl__shizhan"] = "出牌阶段限两次，你可令一名其他角色视为对你使用【决斗】。",
  ["#kl__shizhan-active"] = "势斩，选择一名其他角色，令其视为对你使用【决斗】",

  ["$kl__yaowu1"] = "有吾在此，解太师烦忧。",
  ["$kl__yaowu2"] = "这些杂兵，我有何惧！",
  ["$kl__shizhan1"] = "看你能坚持几个回合！",
  ["$kl__shizhan2"] = "兀那汉子，且报上名来！",
  ["~kl__huaxiong"] = "我掉以轻心了……",
}
----------------------------------------------------------------------------
local xuyou = General(extension, "kl__xuyou", "qun", 3)
local kl__shicai = fk.CreateTriggerSkill {
  name = "kl__shicai",
  events = { fk.CardUseFinished },
  anim_type = "drawCard",
  can_trigger = function(self, event, target, player, data)
    if target ~= player or not player:hasSkill(self) then return false end
    local card_type = data.card.type
    local room = player.room
    if card_type == Card.TypeEquip then
      if not table.contains(player:getCardIds(Player.Equip), data.card:getEffectiveId()) then return false end
    else
      if room:getCardArea(data.card) ~= Card.Processing then return false end
    end
    local logic = room.logic
    local use_event = logic:getCurrentEvent()
    local mark_name = "kl__shicai_" .. data.card:getTypeString() .. "-turn"
    local mark = player:getMark(mark_name)
    if mark == 0 then
      logic:getEventsOfScope(GameEvent.UseCard, 1, function(e)
        local last_use = e.data[1]
        if last_use.from == player.id and last_use.card.type == card_type then
          mark = e.id
          room:setPlayerMark(player, mark_name, mark)
          return true
        end
        return false
      end, Player.HistoryTurn)
    end
    return mark == use_event.id
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local toPut = data.card:isVirtual() and data.card.subcards or { data.card.id }

    if #toPut > 1 then
      toPut = room:askForGuanxing(player, toPut, { #toPut, #toPut }, { 0, 0 }, self.name, true).top
      toPut = table.reverse(toPut)
    end

    room:moveCardTo(toPut, Card.DrawPile, nil, fk.ReasonPut, self.name, nil, true)
    player:drawCards(1, self.name)
  end,

  refresh_events = { fk.AfterCardUseDeclared },
  can_refresh = function(self, event, target, player, data)
    return player == target and player:hasSkill(self, true)
  end,
  on_refresh = function(self, event, target, player, data)
    local typesRecorded = player:getTableMark("@[cardtypes]kl__shicai-turn")
    table.insertIfNeed(typesRecorded, data.card.type)
    player.room:setPlayerMark(player, "@[cardtypes]kl__shicai-turn", typesRecorded)
  end,
}
local kl__cunmu = fk.CreateTriggerSkill {
  name = "kl__cunmu",
  events = { fk.BeforeDrawCard },
  anim_type = "negative",
  frequency = Skill.Compulsory,
  on_use = function(self, event, target, player, data)
    data.fromPlace = "bottom"
  end,
}
xuyou:addSkill(kl__shicai)
xuyou:addSkill(kl__cunmu)
Fk:loadTranslationTable {
  ["kl__xuyou"] = "许攸",
  ["#kl__xuyou"] = "朝秦暮楚",
  ["designer:kl__xuyou"] = "官方&抗绿先锋",

  ["kl__shicai"] = "恃才",
  [":kl__shicai"] = "当你每回合首次使用一种类别的牌后，你可将之置于牌堆顶，然后摸一张牌。",
  ["kl__cunmu"] = "寸目",
  [":kl__cunmu"] = "锁定技，当你摸牌时，改为从牌堆底摸牌。",
  ["@[cardtypes]kl__shicai-turn"] = "恃才",

  ["$chenglue1"] = "成略在胸，良计速出。",
  ["$chenglue2"] = "吾有良略在怀，必为阿瞒所需。",
  ["$kl__shicai1"] = "吾才满腹，袁本初竟不从之。",
  ["$kl__shicai2"] = "阿瞒有我良计，取冀州便是易如反掌。",
  ["$kl__cunmu_kl__xuyou1"] = "哼！目光所及，短寸之间。",
  ["$kl__cunmu_kl__xuyou2"] = "狭目之见，只能窥底。",
  ["~kl__xuyou"] = "阿瞒，没有我你得不到冀州啊！",
}
----------------------------------------------------------------------------
local yuanshu = General(extension, "kl__yuanshu", "qun", 4)
local kl__yongsi = fk.CreateTriggerSkill {
  name = "kl__yongsi",
  anim_type = "drawcard",
  frequency = Skill.Compulsory,
  events = { fk.EventPhaseStart },
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) then
      if event == fk.EventPhaseStart then
        return player.phase == Player.Draw or player.phase == Player.Discard
      end
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local num = 0
    for _, v in pairs(H.getKingdomPlayersNum(room)) do
      if v and v > 0 then
        num = num + 1
      end
    end
    if event == fk.EventPhaseStart and player.phase == Player.Draw then
      player:drawCards(num, self.name)
    else
      player.room:askForDiscard(player, num, num, true, self.name, false, ".",
        "#kl__yongsi-discard:::" .. num)
    end
  end,
}

yuanshu:addSkill(kl__yongsi)
Fk:loadTranslationTable {
  ["kl__yuanshu"] = "袁术",
  ["#kl__yuanshu"] = "仲家帝",
  ["designer:kl__yuanshu"] = "官方&抗绿先锋",

  ["kl__yongsi"] = "庸肆",
  [":kl__yongsi"] = "锁定技，摸牌阶段开始时，你摸X张牌。弃牌阶段开始时，你弃置X张牌（X为势力数）。",
  ["#kl__yongsi-discard"] = "庸肆：你需弃掉等同于场上现存势力数的牌（%arg张）",

  ["$kl__yongsi1"] = "大汉天下，已半入我手！",
  ["$kl__yongsi2"] = "玉玺在手，天下我有！",
  ["$weidi1"] = "你们都得听我的号令！",
  ["$weidi2"] = "我才是皇帝！",
  ["~kl__yuanshu"] = "可恶！就差……一步了……",
}
----------------------------------------------------------------------------
local gongsunyuan = General(extension, "kl__gongsunyuan", "qun", 4)
local kl__huaiyi = fk.CreateActiveSkill {
  name = "kl__huaiyi",
  anim_type = "control",
  card_num = 0,
  target_num = 0,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0 and not player:isKongcheng()
  end,
  card_filter = Util.FalseFunc,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local cards = player.player_cards[Player.Hand]
    player:showCards(cards)
    local colors = {}
    for _, id in ipairs(cards) do
      if Fk:getCardById(id).color ~= Card.NoColor then
        table.insertIfNeed(colors, Fk:getCardById(id):getColorString())
      end
    end
    if #colors < 2 then return end
    local color = room:askForChoice(player, colors, self.name)
    local throw = {}
    for _, id in ipairs(cards) do
      if Fk:getCardById(id):getColorString() == color and not player:prohibitDiscard(Fk:getCardById(id)) then
        table.insert(throw, id)
      end
    end
    if #throw == 0 then return end
    room:throwCard(throw, self.name, player, player)
    if player.dead then return end
    local targets = room:askForChoosePlayers(player, table.map(table.filter(room:getOtherPlayers(player), function(p)
      return (not p:isNude())
    end), Util.IdMapper), 1, #throw, "#kl__huaiyi-choose:::" .. tostring(#throw), self.name, true)
    if #targets > 0 then
      room:sortPlayersByAction(targets)
      local n = 0
      for _, p in ipairs(targets) do
        if player.dead then return end
        local to = room:getPlayerById(p)
        if not to:isNude() then
          local id = room:askForCardChosen(player, to, "he", self.name)
          n = n + 1
          room:moveCardTo(id, Card.PlayerHand, player, fk.ReasonPrey, self.name, nil, false, player.id)
        end
      end
    end
  end,
}
gongsunyuan:addSkill(kl__huaiyi)
Fk:loadTranslationTable {
  ["kl__gongsunyuan"] = "公孙渊",
  ["#kl__gongsunyuan"] = "狡徒悬海",
  ["designer:kl__gongsunyuan"] = "官方&抗绿先锋",

  ["kl__huaiyi"] = "怀异",
  [":kl__huaiyi"] = "出牌阶段限一次，你可展示所有手牌，若其中包含两种颜色，则你弃置其中一种颜色的牌，然后获得至多X名角色的各一张牌（X为你以此法弃置的手牌数）。",
  ["#kl__huaiyi-choose"] = "怀异：你可以获得至多%arg名角色各一张牌",

  ["$kl__huaiyi1"] = "此等小利，焉能安吾雄心？",
  ["$kl__huaiyi2"] = "一生纵横，怎可对他人称臣！",
  ["~kl__gongsunyuan"] = "天不容我公孙家……",
}
----------------------------------------------------------------------------
local tianchou = General(extension, "kl__tianchou", "qun", 4)
local kl__shandao = fk.CreateActiveSkill {
  name = "kl__shandao",
  anim_type = "offensive",
  card_num = 0,
  min_target_num = 1,
  prompt = "#kl__shandao-active",
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  card_filter = Util.FalseFunc,
  target_filter = function(self, to_select, selected)
    return not Fk:currentRoom():getPlayerById(to_select):isNude()
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local targets = table.simpleClone(effect.tos)
    room:sortPlayersByAction(targets)
    local tos = {}
    for _, id in ipairs(targets) do
      local target = room:getPlayerById(id)
      table.insert(tos, target)
      if not (target.dead or target:isNude()) then
        local card = room:askForCardChosen(player, target, "he", self.name)
        room:moveCards({
          ids = { card },
          from = target.id,
          toArea = Card.DrawPile,
          moveReason = fk.ReasonPut,
          skillName = self.name,
        })
        if player.dead then return false end
      end
    end
    tos = table.filter(tos, function(p)
      return not p.dead
    end)
    room:useVirtualCard("amazing_grace", {}, player, tos, self.name)
    if player.dead then return false end
    local others = table.filter(room.alive_players, function(p)
      return not table.contains(targets, p.id) and p ~= player
    end)
    room:useVirtualCard("archery_attack", {}, player, others, self.name)
  end,
}
tianchou:addSkill(kl__shandao)
Fk:loadTranslationTable {
  ["kl__tianchou"] = "田畴",
  ["#kl__tianchou"] = "乱世族隐",
  ["designer:kl__tianchou"] = "官方",

  ["kl__shandao"] = "善刀",
  [":kl__shandao"] = "出牌阶段限一次，你可将至少一名角色的各一张牌置于牌堆顶，视为对这些角色使用一张【五谷丰登】，" ..
      "然后视为对除这些角色外的其他角色使用一张【万箭齐发】。",
  ["#kl__shandao-active"] = "发动 善刀，选择至少一名有牌的角色",

  ["$kl__shandao1"] = "君子藏器，待天时而动。",
  ["$kl__shandao2"] = "善刀而藏之，可解充栋之牛。",
  ["~kl__tianchou"] = "吾罪大矣，何堪封侯之荣……",
}
----------------------------------------------------------------------------
local liubiao = General(extension, "kl__liubiao", "qun", 3)
-- local kl__zishou = fk.CreateTriggerSkill {
--   name = "kl__zishou",
--   anim_type = "drawcard",
--   events = { fk.EventPhaseStart },
--   can_trigger = function(self, event, target, player, data)
--     if target == player and player:hasSkill(self) then
--       if event == fk.EventPhaseStart then
--         return player.phase == Player.Play
--       end
--       return true
--     end
--   end,
--   on_use = function(self, event, target, player, data)
--     local room = player.room
--     room:addPlayerMark(player, "@kl__zishou-turn", 1)
--     local num = 0
--     for _, v in pairs(H.getKingdomPlayersNum(room)) do
--       if v and v > 0 then
--         num = num + 1
--       end
--     end
--     player:drawCards(num, self.name)
--   end,
-- }
-- local zishou_prohibit = fk.CreateProhibitSkill {
--   name = "#zishou_prohibit",
--   is_prohibited = function(self, from, to, card)
--     if from:hasSkill(self) then
--       return from:usedSkillTimes("kl__zishou") > 0 and from ~= to
--     end
--   end,
-- }
-- local kl__zishou_mod = fk.CreateMaxCardsSkill {
--   name = "#kl__zishou_mod",
--   correct_func = function(self, player)
--     if player:hasSkill(self) and player:getMark("@kl__zishou-turn") > 0 then
--       local kingdoms = {}
--       for _, p in ipairs(Fk:currentRoom().alive_players) do
--         table.insertIfNeed(kingdoms, p.kingdom)
--       end
--       return #kingdoms
--     else
--       return 0
--     end
--   end,
-- }
-- kl__zishou:addRelatedSkill(zishou_prohibit)
-- kl__zishou:addRelatedSkill(kl__zishou_mod)
-- liubiao:addSkill(kl__zishou)
-- Fk:loadTranslationTable {
--   ["kl__liubiao"] = "刘表",
--   ["#kl__liubiao"] = "跨蹈汉南",
--   ["designer:kl__liubiao"] = "官方&抗绿先锋",

--   ["kl__zishou"] = "自守",
--   [":kl__zishou"] = "出牌阶段开始时，你可摸X张牌。若如此做，本回合你使用牌不能指定其他角色为目标且本回合你的手牌上限+X（X为势力数）。",
--   ["@kl__zishou-turn"] = "自守",

--   ["$kl__zishou1"] = "荆襄之地，固若金汤。",
--   ["$kl__zishou2"] = "江河霸主，何惧之有？",
--   ["~kl__liubiao"] = "优柔寡断，要不得啊。",
-- }
local yansha = fk.CreateActiveSkill {
  name = "yansha",
  anim_type = "control",
  card_num = 0,
  min_target_num = 1,
  prompt = "#yansha",
  can_use = function(self, player)
    return
        player:usedSkillTimes(self.name, Player.HistoryPhase) == 0 and
        player:canUse(Fk:cloneCard("amazing_grace"))
  end,
  card_filter = Util.FalseFunc,
  target_filter = function(self, to_select, selected)
    return Self:canUseTo(Fk:cloneCard("amazing_grace"), Fk:currentRoom():getPlayerById(to_select))
  end,
  on_use = function(self, room, effect)
    local amazingGrace = Fk:cloneCard("amazing_grace")
    amazingGrace.skillName = self.name

    local useData = {
      from = effect.from,
      tos = table.map(effect.tos, function(to) return { to } end),
      card = amazingGrace,
    }
    room:useCard(useData)

    local targets = TargetGroup:getRealTargets(useData.tos)
    if #targets > 0 then
      for _, p in ipairs(room:getAlivePlayers()) do
        if p:isAlive() and not table.contains(targets, p.id) then
          room:setPlayerMark(p, self.name, TargetGroup:getRealTargets(useData.tos))
          local success, dat = room:askForUseViewAsSkill(
            p,
            "yanshaViewas",
            "#yansha-slash",
            true,
            { bypass_times = true, bypass_distances = true }
          )
          room:setPlayerMark(p, self.name, 0)

          if success then
            local card = Fk.skills["yanshaViewas"]:viewAs(dat.cards)
            table.removeOne(card.skillNames, "yanshaSlash")
            room:useCard {
              from = p.id,
              tos = table.map(dat.targets, function(toId) return { toId } end),
              card = card,
              extraUse = true,
            }
          end
        end
      end
    end
  end,
}
local yanshaViewas = fk.CreateViewAsSkill {
  name = "yanshaViewas",
  pattern = "slash",
  handly_pile = true,
  card_filter = function(self, to_select, selected)
    return #selected == 0 and Fk:getCardById(to_select).type == Card.TypeEquip
  end,
  view_as = function(self, cards)
    if #cards ~= 1 then return end
    local card = Fk:cloneCard("slash")
    card:addSubcard(cards[1])
    card.skillName = "yanshaSlash"
    return card
  end,
}
local yanshaProhibit = fk.CreateProhibitSkill {
  name = "#yansha_prohibit",
  is_prohibited = function(self, from, to, card)
    return
        card and
        table.contains(card.skillNames, "yanshaSlash") and
        not table.contains(from:getTableMark(yansha.name), to.id)
  end,
}
Fk:addSkill(yanshaViewas)
yansha:addRelatedSkill(yanshaProhibit)
liubiao:addSkill(yansha)
local qingping = fk.CreateTriggerSkill {
  name = "qingping",
  events = { fk.EventPhaseStart },
  can_trigger = function(self, event, target, player, data)
    return
        target == player and
        player:hasSkill(self) and
        player.phase == Player.Finish and
        not table.find(
          player.room.alive_players,
          function(p)
            return
                player:inMyAttackRange(p) and
                (
                  p:getHandcardNum() < 1 or
                  p:getHandcardNum() > player:getHandcardNum()
                )
          end
        )
  end,
  on_use = function(self, event, target, player, data)
    local targetNum = #table.filter(
      player.room.alive_players,
      function(p)
        return
            player:inMyAttackRange(p) and
            p:getHandcardNum() > 0 and
            p:getHandcardNum() <= player:getHandcardNum()
      end
    )
    player:drawCards(targetNum, self.name)
  end,
}
liubiao:addSkill(qingping)
Fk:loadTranslationTable {
  ["kl__liubiao"] = "刘表",
  ["#kl__liubiao"] = "单骑入荆",

  ["yansha"] = "宴杀",
  [":yansha"] = "出牌阶段限一次，你可以视为使用一张以至少一名角色为目标的【五谷丰登】，" ..
      "然后所有非目标角色依次可以将一张装备牌当做无距离限制的【杀】对其中一名目标角色使用。",
  ["#yansha"] = "宴杀：你可视为使用指定任意目标的【五谷丰登】，结算后非目标可将装备当【杀】对目标使用",
  ["yanshaViewas"] = "宴杀",
  ["#yansha-slash"] = "宴杀：你可以将一张装备牌当无距离限制的【杀】对其中一名角色使用",
  ["qingping"] = "清平",
  [":qingping"] = "结束阶段开始时，若你攻击范围内的角色手牌数均大于0且不大于你，则你可以摸等同于这些角色数的牌。",
}
----------------------------------------------------------------------------
local chengui = General(extension, "kl__chengui", "qun", 3)
local kl__yingtu = fk.CreateTriggerSkill {
  name = "kl__yingtu",
  anim_type = "control",
  events = { fk.AfterCardsMove },
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) and player:usedSkillTimes(self.name) == 0 then
      for _, move in ipairs(data) do
        if move.to ~= nil and move.toArea == Card.PlayerHand then
          local p = player.room:getPlayerById(move.to)
          if p.phase ~= Player.Draw and (p:getNextAlive() == player or player:getNextAlive() == p) and not p:isNude() then
            return true
          end
        end
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local targets = {}
    for _, move in ipairs(data) do
      if move.to ~= nil and move.toArea == Card.PlayerHand then
        local p = player.room:getPlayerById(move.to)
        if p.phase ~= Player.Draw and (p:getNextAlive() == player or player:getNextAlive() == p) and not p:isNude() then
          table.insertIfNeed(targets, move.to)
        end
      end
    end
    if #targets == 1 then
      if room:askForSkillInvoke(player, self.name, nil, "#kl__yingtu-invoke::" .. targets[1]) then
        room:doIndicate(player.id, targets)
        self.cost_data = targets[1]
        return true
      end
    elseif #targets > 1 then
      local tos = room:askForChoosePlayers(player, targets, 1, 1, "#kl__yingtu-invoke-multi", self.name, true)
      if #tos > 0 then
        self.cost_data = tos[1]
        return true
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local from = room:getPlayerById(self.cost_data)
    local lastplayer = (player:getNextAlive() == from)
    local card = room:askForCardChosen(player, from, "he", self.name)
    room:obtainCard(player.id, card, false, fk.ReasonPrey)
    if player.dead or player:isNude() then return false end
    local to = player:getNextAlive()
    if lastplayer then
      to = player:getLastAlive()
    end
    if to == nil or to == player then return false end
    local id = room:askForCard(player, 1, 1, true, self.name, false, ".", "#kl__yingtu-choose::" .. to.id)[1]
    room:obtainCard(to, id, false, fk.ReasonGive)
    local card = Fk:getCardById(id)
    if card.type == Card.TypeEquip and not to.dead and table.contains(to:getCardIds("h"), id) and not to:isProhibited(to, card) then
      room:useCard({
        from = to.id,
        tos = { { to.id } },
        card = card,
      })
    end
  end,
}
local kl__congshi = fk.CreateTriggerSkill {
  name = "kl__congshi",
  anim_type = "drawcard",
  frequency = Skill.Compulsory,
  events = { fk.CardUseFinished },
  can_trigger = function(self, event, target, player, data)
    return not target.dead and player:hasSkill(self) and data.card.type == Card.TypeEquip and
        table.every(player.room.alive_players, function(p)
          return p == target or #target:getCardIds("e") > #p:getCardIds("e")
        end)
  end,
  on_use = function(self, event, target, player, data)
    player:drawCards(1, self.name)
  end,
}
chengui:addSkill(kl__yingtu)
chengui:addSkill(kl__congshi)
Fk:loadTranslationTable {
  ["kl__chengui"] = "陈珪",
  ["#kl__chengui"] = "弄虎如婴",
  ["designer:kl__chengui"] = "官方&抗绿先锋",

  ["kl__yingtu"] = "营图",
  [":kl__yingtu"] = "每回合限一次，当你的上家/下家于其摸牌阶段外获得牌后，你可获得其一张牌，交给你的下家/上家一张牌。" ..
      "若此牌为装备牌，获得牌的角色使用之。",
  ["kl__congshi"] = "从势",
  [":kl__congshi"] = "锁定技，当一名角色使用装备牌后，若其装备区里的牌数为全场唯一最多的，你摸一张牌。",
  ["#kl__yingtu-invoke"] = "营图：你可以获得 %dest 的一张牌",
  ["#kl__yingtu-invoke-multi"] = "营图：你可以获得上家或下家的一张牌",
  ["#kl__yingtu-choose"] = "营图：选择一张牌交给 %dest，若为装备牌则其使用之",

  ["$kl__yingtu1"] = "不过略施小计，聊戏莽夫耳。",
  ["$kl__yingtu2"] = "栖虎狼之侧，安能不图存身？",
  ["$kl__congshi1"] = "阁下奉天子以令诸侯，珪自当相从。",
  ["$kl__congshi2"] = "将军率六师以伐不臣，珪何敢相抗？",
  ["~kl__chengui"] = "终日戏虎，竟为虎所噬。",
}
----------------------------------------------------------------------------
local shixie = General(extension, "kl__shixie", "qun", 3)
local kl__biluan = fk.CreateTriggerSkill {
  name = "kl__biluan",
  anim_type = "defensive",
  events = { fk.EventPhaseStart },
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) and player.phase == Player.Finish then
      return table.find(player.room:getOtherPlayers(player), function(p) return p:distanceTo(player) == 1 end)
    end
  end,
  on_cost = function(self, event, target, player, data)
    local x = math.min(4, #player.room.alive_players)
    local card = player.room:askForDiscard(player, 1, 1, true, self.name, true, ".", "#kl__biluan-invoke:::" .. x, true)
    if #card > 0 then
      self.cost_data = card
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:throwCard(self.cost_data, self.name, player, player)

    local kingdoms = {}
    for _, p in ipairs(Fk:currentRoom().alive_players) do
      table.insertIfNeed(kingdoms, p.kingdom)
    end

    local x = #kingdoms
    local num = tonumber(player:getMark("@kl__shixie_distance")) + x
    room:setPlayerMark(player, "@kl__shixie_distance", num > 0 and "+" .. num or num)
  end,
}
local kl__biluan_distance = fk.CreateDistanceSkill {
  name = "#kl__biluan_distance",
  correct_func = function(self, from, to)
    local num = tonumber(to:getMark("@kl__shixie_distance"))
    if num > 0 then
      return num
    end
  end,
}
kl__biluan:addRelatedSkill(kl__biluan_distance)
shixie:addSkill(kl__biluan)
local kl__lixia = fk.CreateTriggerSkill {
  name = "kl__lixia",
  anim_type = "drawcard",
  frequency = Skill.Compulsory,
  events = { fk.EventPhaseStart },
  can_trigger = function(self, event, target, player, data)
    return target ~= player and player:hasSkill(self) and target.phase == Player.Start and
        not target:inMyAttackRange(player)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local choice = room:askForChoice(player, { "draw1", "kl__lixia_draw:" .. target.id }, self.name)
    if choice == "draw1" then
      player:drawCards(1, self.name)
    else
      target:drawCards(1, self.name)
    end
    local num = tonumber(player:getMark("@kl__shixie_distance")) - 1
    room:setPlayerMark(player, "@kl__shixie_distance", num > 0 and "+" .. num or num)
  end,
}
local kl__lixia_distance = fk.CreateDistanceSkill {
  name = "#kl__lixia_distance",
  correct_func = function(self, from, to)
    local num = tonumber(to:getMark("@kl__shixie_distance"))
    if num < 0 then
      return num
    end
  end,
}
kl__lixia:addRelatedSkill(kl__lixia_distance)
shixie:addSkill(kl__lixia)
Fk:loadTranslationTable {
  ["kl__shixie"] = "士燮",
  ["#kl__shixie"] = "雄长百越",
  ["designer:kl__shixie"] = "官方&抗绿先锋",

  ["kl__biluan"] = "避乱",
  [":kl__biluan"] = "结束阶段，若有角色至你距离为1，你可弃置一张牌，令其他角色至你的距离+X（X为势力数）。",
  ["kl__lixia"] = "礼下",
  [":kl__lixia"] = "锁定技，其他角色的准备阶段，若你不在其攻击范围内，你可令你或其摸一张牌，然后其他角色至你距离-1。",
  ["#kl__biluan-invoke"] = "避乱：你可弃一张牌，令其他角色计算与你距离+%arg",
  ["@kl__shixie_distance"] = "距离",
  ["kl__lixia_draw"] = "令%src摸一张牌",

  ["$kl__biluan1"] = "身处乱世，自保足矣。",
  ["$kl__biluan2"] = "避一时之乱，求长世安稳。",
  ["$kl__lixia1"] = "将军真乃国之栋梁。",
  ["$kl__lixia2"] = "英雄可安身立命于交州之地。",
  ["~kl__shixie"] = "我这一生，足矣……",
}
----------------------------------------------------------------------------
local jvshou = General(extension, "kl__jvshou", "qun", 3)
local kl__jianying = fk.CreateTriggerSkill {
  name = "kl__jianying",
  events = { fk.CardUsing },
  can_trigger = function(self, event, target, player, data)
    if player ~= target or not player:hasSkill(self) then return false end
    local room = player.room
    local logic = room.logic
    local use_event = logic:getCurrentEvent()
    local events = logic.event_recorder[GameEvent.UseCard] or Util.DummyTable
    local last_find = false
    for i = #events, 1, -1 do
      local e = events[i]
      if e.data[1].from == player.id then
        if e.id == use_event.id then
          last_find = true
        elseif last_find then
          local last_use = e.data[1]
          return data.card:compareSuitWith(last_use.card) or data.card:compareNumberWith(last_use.card)
        end
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    player:drawCards(1, self.name)
  end,

  refresh_events = { fk.AfterCardUseDeclared, fk.EventLoseSkill },
  can_refresh = function(self, event, target, player, data)
    if event == fk.AfterCardUseDeclared then
      return target == player and player:hasSkill(self, true)
    elseif event == fk.EventLoseSkill then
      return data == self
    end
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    if event == fk.AfterCardUseDeclared then
      room:setPlayerMark(player, "@kl__jianying", { data.card:getSuitString(true), data.card:getNumberStr() })
    elseif event == fk.EventLoseSkill then
      room:setPlayerMark(player, "@kl__jianying", 0)
    end
  end,
}
local kl__shibei = fk.CreateTriggerSkill {
  name = "kl__shibei",
  mute = true,
  anim_type = "defensive",
  frequency = Skill.Compulsory,
  events = { fk.Damaged },
  on_use = function(self, event, target, player, data)
    local room = player.room
    if data.isVirtualDMG then return end -- 虚拟伤害别管了
    local firstDamage = room.logic:getActualDamageEvents(1, function(e) return e.data[1].to == player end)[1]
    if firstDamage and firstDamage.data[1] == data then
      player:broadcastSkillInvoke(self.name, 1)
      room:notifySkillInvoked(player, self.name)
      if player:isWounded() then
        room:recover {
          who = player,
          num = 1,
          skillName = self.name
        }
      end
    else
      player:broadcastSkillInvoke(self.name, 2)
      room:notifySkillInvoked(player, self.name, "negative")
      room:loseHp(player, 1, self.name)
    end
  end,
}
jvshou:addSkill(kl__jianying)
jvshou:addSkill(kl__shibei)
Fk:loadTranslationTable {
  ["kl__jvshou"] = "沮授",
  ["#kl__jvshou"] = "监军谋国",
  ["designer:kl__jushou"] = "官方",

  ["kl__jianying"] = "渐营",
  [":kl__jianying"] = "当你使用牌时，若此牌与你使用的上一张牌点数或花色相同，你可以摸一张牌。",
  ["kl__shibei"] = "矢北",
  [":kl__shibei"] = "锁定技，当你受到伤害后，若此伤害是你本回合第一次受到的伤害，你回复1点体力；否则你失去1点体力。",
  ["@kl__jianying"] = "渐营",

  ["$kl__jianying1"] = "由缓至急，循循而进。",
  ["$kl__jianying2"] = "事需缓图，欲速不达也。",
  ["$kl__shibei1"] = "矢志于北，尽忠于国！",
  ["$kl__shibei2"] = "命系袁氏，一心向北。",
  ["~kl__jvshou"] = "智士凋亡，河北哀矣……",
}

local yuantanyuanshang = General(extension, "kl__yuantanyuanshang", "qun", 4)
local kl__dikai = fk.CreateViewAsSkill {
  name = "kl__dikai",
  anim_type = "offensive",
  pattern = "slash",
  prompt = "#kl__dikai-active",
  handly_pile = true,
  card_filter = function(self, to_select, selected)
    return Fk:currentRoom():getCardArea(to_select) ~= Player.Equip
  end,
  view_as = function(self, cards)
    if #cards < 2 then
      return nil
    end
    local c = Fk:cloneCard("slash")
    c.skillName = self.name
    c:addSubcards(cards)
    return c
  end,
  enabled_at_play = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryTurn) < 1
  end,
  enabled_at_response = Util.FalseFunc,
  before_use = function(self, player, useData)
    useData.extra_data = useData.extra_data or {}
    useData.extra_data.kl__dikaiUser = player.id
  end,
}
local kl__dikai__after = fk.CreateTriggerSkill {
  name = "#kl__dikai__after",
  anim_type = "offensive",
  visible = false,
  events = { fk.CardEffectCancelledOut },
  mute = true, -- 技能触发时不播放音效
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and data.from == player.id and data.card.trueName == "slash" and
        table.contains(data.card.skillNames, "kl__dikai")
  end,
  on_use = function(self, event, target, player, data)
    local num = #data.card.subcards
    player.room:drawCards(player, num, self.name)
  end,
}
local kl__zhengsi = fk.CreateTriggerSkill {
  name = "kl__zhengsi",
  events = { fk.EventPhaseEnd },
  frequency = Skill.Compulsory,
  can_trigger = function(self, event, target, player, data)
    if target.phase == Player.Finish and player:hasSkill(self.name) and player:getHandcardNum() ~= 2 then
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local num = player:getHandcardNum()
    if num > 2 then
      room:askForDiscard(player, num - 2, num - 2, false, self.name, false)
    elseif num < 2 then
      player:drawCards(2 - num, self.name)
    end
  end
}
yuantanyuanshang:addSkill(kl__dikai)
yuantanyuanshang:addSkill(kl__zhengsi)
kl__dikai:addRelatedSkill(kl__dikai__after)
Fk:loadTranslationTable {
  ["kl__yuantanyuanshang"] = "袁谭袁尚",
  ["#kl__yuantanyuanshang"] = "兄弟阋墙",
  ["designer:kl__yuantanyuanshang"] = "3d吧赛",

  ["kl__dikai"] = "敌忾",
  [":kl__dikai"] = "每回合限一次，你可将至少两张手牌当【杀】使用。当此【杀】被【闪】抵消后，你摸等量张牌。",
  ["#kl__dikai-active"] = "敌忾：你可将至少两张手牌当【杀】使用",
  ["#kl__dikai__after"] = "敌忾",
  ["kl__zhengsi"] = "争嗣",
  [":kl__zhengsi"] = "锁定技，每名角色的结束阶段，你将手牌数调整至2。",

  ["$kl__dikai1"] = "自相恩残，相煎何急。",
  ["$kl__dikai2"] = "同室内伐，贻笑外人。",
  ["$kl__zhengsi1"] = "今日吾掌中之剑，必要饮兄弟之血！",
  ["$kl__zhengsi2"] = "外有强敌环伺，汝二人不欲助我、奈何助贼！",
  ["~kl__yuantanyuanshang"] = "兄弟难齐心，该有此果……",
}

local kongrong = General(extension, "kl__kongrong", "qun", 3)
local kl__mingshi = fk.CreateTriggerSkill {
  name = "kl__mingshi",
  anim_type = "defensive",
  frequency = Skill.Compulsory,
  events = { fk.DamageInflicted },
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and data.from
  end,
  on_use = function(self, event, target, player, data)
    if #player.room:askForDiscard(data.from, 1, 1, false, self.name, true, nil, "#kl__mingshi-invoke:" .. player.id) == 0 then
      data.damage = data.damage - 1
    end
  end,
}
local kl__lirang = fk.CreateTriggerSkill {
  name = "kl__lirang",
  events = { fk.AfterCardsMove },
  can_trigger = function(self, event, target, player, data)
    if not player:hasSkill(self) or player:usedSkillTimes(self.name) ~= 0 then return false end
    local ids = {}
    for _, move in ipairs(data) do
      if move.to == player.id and move.toArea == Card.PlayerHand and move.skillName ~= self.name then
        for _, info in ipairs(move.moveInfo) do
          if table.contains(player.player_cards[Player.Hand], info.cardId) then
            table.insertIfNeed(ids, info.cardId)
          end
        end
      end
    end
    if #ids > 0 then
      self.cost_data = { cards = ids }
      return true
    end
  end,
  on_cost = function(self, event, target, player, data)
    return player.room:askForSkillInvoke(player, self.name, nil, "#kl__lirang-invoke")
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local cards = self.cost_data.cards
    room:askForYiji(player, cards, room:getOtherPlayers(player), self.name, 1, 999)
    room:drawCards(player, 1, self.name)
  end
}
kongrong:addSkill(kl__mingshi)
kongrong:addSkill(kl__lirang)
Fk:loadTranslationTable {
  ["kl__kongrong"] = "孔融",
  ["#kl__kongrong"] = "凛然重义",
  ["designer:kl__kongrong"] = "官方&抗绿先锋",

  ["kl__mingshi"] = "名士",
  [":kl__mingshi"] = "锁定技，当你受到伤害时，来源选择一项：1.弃置一张手牌；2.此伤害-1。",
  ["kl__lirang"] = "礼让",
  [":kl__lirang"] = "每回合限一次，当你获得牌后，你可分配其中至少一张牌，然后你摸一张牌。",
  ["#kl__mingshi-invoke"] = "名士：请弃置一张手牌，否则你对 %src 造成的伤害-1",
  ["#kl__lirang-invoke"] = "礼让：你可将这些牌分配给任意角色",

  ["$kl__mingshi1"] = "孔门之后，忠孝为先。",
  ["$kl__mingshi2"] = "名士之风，仁义高洁。",
  ["$kl__lirang1"] = "夫礼先王以承天之道，以治人之情。",
  ["$kl__lirang2"] = "谦者，德之柄也，让者，礼之逐也。",
  ["~kl__kongrong"] = "覆巢之下，岂有完卵……",
}
----------------------------------------------------------------------------
local lvbu = General(extension, "kl__lvbu", "qun", 4)
local kl__wushuang = fk.CreateTriggerSkill {
  name = "kl__wushuang",
  anim_type = "offensive",
  frequency = Skill.Compulsory,
  events = { fk.TargetSpecified, fk.TargetConfirmed },
  can_trigger = function(self, event, target, player, data)
    if not player:hasSkill(self) then
      return false
    end

    if event == fk.TargetSpecified then
      return target == player and table.contains({ "slash", "duel" }, data.card.trueName)
    else
      return data.to == player.id and data.card.trueName == "duel"
    end
  end,
  on_use = function(self, event, target, player, data)
    data.fixedResponseTimes = data.fixedResponseTimes or {}
    if data.card.trueName == "slash" then
      data.fixedResponseTimes["jink"] = 2
    else
      data.fixedResponseTimes["slash"] = 2
      data.fixedAddTimesResponsors = data.fixedAddTimesResponsors or {}
      table.insert(data.fixedAddTimesResponsors, (event == fk.TargetSpecified and data.to or data.from))
    end
  end,
}
local kl__wuqian = fk.CreateActiveSkill {
  name = "kl__wuqian",
  anim_type = "offensive",
  card_num = 0,
  target_num = 1,
  prompt = "#kl__wuqian",
  can_use = function(self, player)
    return not player:prohibitUse(Fk:cloneCard("duel")) and player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  card_filter = Util.FalseFunc,
  target_filter = function(self, to_select, selected, selected_cards)
    local target = Fk:currentRoom():getPlayerById(to_select)
    return #selected == 0 and not Self:isProhibited(target, Fk:cloneCard("duel"))
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local target = room:getPlayerById(effect.tos[1])
    -- 创建带有标记的虚拟决斗
    local use = {
      from = effect.from,
      tos = { { effect.tos[1] } },
      card = Fk:cloneCard("duel"),
      extra_data = { kl__wuqian = true },
      skillName = self.name
    }
    room:useCard(use)
  end,
}

local kl__wuqian_delay = fk.CreateTriggerSkill {
  name = "#kl__wuqian_delay",
  mute = true,
  events = { fk.AskForCardUse },
  can_trigger = function(self, event, target, player, data)
    -- 检查是否是目标角色需要出杀
    if target == player and
        (data.cardName == "slash" or (data.pattern and Exppattern:Parse(data.pattern):matchExp("slash|0|nosuit|none"))) and
        (data.extraData == nil or data.extraData.kl__wuqian_ask == nil) then
      local e = player.room.logic:getCurrentEvent():findParent(GameEvent.UseCard)
      if e then
        local use = e.data[1]
        -- 检查是否是带有无前标记的决斗
        if use.card.trueName == "duel" and use.extra_data and use.extra_data.kl__wuqian then
          -- 获取所有其他存活角色作为可能的代替者
          local others = table.filter(player.room.alive_players, function(p)
            return p.id ~= player.id
          end)
          if #others > 0 then
            self.cost_data = others
            return true
          end
        end
      end
    end
    return false
  end,

  on_cost = function(self, event, target, player, data)
    return player.room:askForSkillInvoke(player, "kl__wuqian", nil, "#kl__wuqian-invoke")
  end,

  on_use = function(self, event, target, player, data)
    local room = player.room
    -- 显示指示线
    room:doIndicate(player.id, { self.cost_data })
    for _, id in ipairs(self.cost_data) do
      local p = room:getPlayerById(id)
      if not p.dead then
        -- 询问是否代替出杀
        local cardResponded = room:askForResponse(p, "slash", "slash", "#kl__wuqian-ask:" .. player.id, true,
          { kl__wuqian_ask = true })
        if cardResponded then
          -- 响应卡牌
          room:responseCard({
            from = p.id,
            card = cardResponded,
            skipDrop = true,
          })
          -- 设置结果
          data.result = {
            from = player.id,
            card = Fk:cloneCard("slash"),
          }
          data.result.card:addSubcards(room:getSubcardsByRule(cardResponded, { Card.Processing }))
          data.result.card.skillName = "kl__wuqian"

          if data.eventData then
            data.result.toCard = data.eventData.toCard
            data.result.responseToEvent = data.eventData.responseToEvent
          end
          return true
        end
      end
    end
  end,
}
lvbu:addSkill(kl__wuqian)
kl__wuqian:addRelatedSkill(kl__wuqian_delay)
lvbu:addSkill(kl__wushuang)
Fk:loadTranslationTable {
  ["kl__lvbu"] = "吕布",
  ["#kl__lvbu"] = "武的化身",

  ["kl__wushuang"] = "无双",
  [":kl__wushuang"] = "当你使用【杀】指定一个目标后，该角色需依次使用两张【闪】才能抵消此【杀】；当你使用【决斗】指定一个目标后，或成为一名角色使用【决斗】的目标后，该角色每次响应此【决斗】需依次打出两张【杀】。",
  ["kl__wuqian"] = "无前",
  [":kl__wuqian"] = "出牌阶段限一次，你可视为使用一张【决斗】，其他角色均可代替目标角色响应此【决斗】。",
  ["#kl__wuqian"] = "无前：你可以视为使用一张【决斗】",
  ["#kl__wuqian-invoke"] = "无前：是否令其他角色选择代替目标角色响应此【决斗】？",
  ["#kl__wuqian-ask"] = "无前：你可替 %src 响应此【决斗】",

  ["$kl__wushuang2"] = "此天下，还有挡我者？",
  ["$kl__wushuang1"] = "画戟扫沙场，无双立万世。",
  ["$kl__wuqian1"] = "别心怀侥幸了，你们不可能赢！",
  ["$kl__wuqian2"] = "虎牢关，我一人镇守足矣。",
  ["~kl__lvbu"] = "不可能……",
}

-- local diaochan = General(extension, "kl__diaochan", "qun", 3, 3, General.Female)
-- local kl__lijian = fk.CreateActiveSkill {
--   name = "kl__lijian",
--   anim_type = "offensive",
--   can_use = function(self, player)
--     return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
--   end,
--   card_filter = function(self, to_select, selected)
--     return #selected == 0
--   end,
--   target_filter = function(self, to_select, selected)
--     return #selected < 2 and to_select ~= Self.id and
--         Fk:currentRoom():getPlayerById(to_select).gender == General.Male
--   end,
--   target_num = 2,
--   min_card_num = 1,
--   on_use = function(self, room, use)
--     local player = room:getPlayerById(use.from)
--     room:throwCard(use.cards, self.name, player, player)
--     local duel = Fk:cloneCard("duel")
--     duel.skillName = self.name
--     local new_use = { ---@type CardUseStruct
--       from = use.tos[2],
--       tos = { { use.tos[1] } },
--       card = duel,
--     }
--     room:useCard(new_use)
--   end,
-- }
-- local kl__biyue = fk.CreateTriggerSkill {
--   name = "kl__biyue",
--   anim_type = "drawcard",
--   events = { fk.EventPhaseStart },
--   can_trigger = function(self, event, target, player, data)
--     return target == player and player:hasSkill(self)
--         and player.phase == Player.Finish
--   end,
--   on_use = function(self, event, target, player, data)
--     local num = 0
--     for _, p in ipairs(Fk:currentRoom().alive_players) do
--       if p:isFemale() then
--         num = num + 1
--       end
--     end
--     player:drawCards(num, self.name)
--   end,
-- }
-- diaochan:addSkill(kl__lijian)
-- diaochan:addSkill(kl__biyue)
-- Fk:loadTranslationTable {
--   ["kl__diaochan"] = "貂蝉",
--   ["#kl__diaochan"] = "绝世的舞姬",
--   ["designer:kl__diaochan"] = "官方&抗绿先锋",

--   ["kl__lijian"] = "离间",
--   [":kl__lijian"] = "出牌阶段限一次，你可弃置一张牌并选择两名其他男性角色，后选择的角色视为对先选择的角色使用一张【决斗】。",
--   ["kl__biyue"] = "闭月",
--   [":kl__biyue"] = "结束阶段，你可摸X张牌(X为女性角色数)。",

--   ["$kl__lijian1"] = "嗯呵呵~~呵呵~~",
--   ["$kl__lijian2"] = "夫君，你要替妾身做主啊……",
--   ["$kl__biyue1"] = "失礼了～",
--   ["$kl__biyue2"] = "羡慕吧～",
--   ["~kl__diaochan"] = "父亲大人，对不起……",
-- }

-- local liuqi = General(extension, "kl__liuqi", "qun", 3, 3, General.Male)
-- local kl__wenji = fk.CreateTriggerSkill {
--   name = "#kl__wenji",
--   anim_type = "control",
--   events = { fk.EventPhaseStart },
--   can_trigger = function(self, event, target, player, data)
--     return target == player and player:hasSkill(self) and player.phase == Player.Play and
--         not table.every(player.room:getOtherPlayers(player, false), function(p) return (p:isNude()) end)
--   end,
--   on_cost = function(self, event, target, player, data)
--     local room = player.room
--     local to = room:askForChoosePlayers(player, table.map(table.filter(room:getOtherPlayers(player, false), function(p)
--       return not p:isNude()
--     end), Util.IdMapper), 1, 1, "#kl__wenji-choose", self.name, true)
--     if #to > 0 then
--       self.cost_data = to[1]
--       return true
--     end
--   end,
--   on_use = function(self, event, target, player, data)
--     local room = player.room
--     local to = room:getPlayerById(self.cost_data)
--     local card = room:askForCard(to, 1, 1, true, self.name, false, ".", "#kl__wenji-give::" .. player.id)
--     local c = Fk:getCardById(card[1]) -- 获取展示的卡牌对象。

--     local names = {}
--     for _, id in ipairs(Fk:getAllCardIds()) do
--       -- 遍历所有卡牌。
--       local card = Fk:getCardById(id)
--       if card.type == Card.TypeTrick and card.sub_type ~= Card.SubtypeDelayedTrick then
--         -- 如果卡牌是普通锦囊牌
--         table.insertIfNeed(names, card.name)
--         -- 将卡牌名称加入 `names` 列表。
--       end
--     end
--     local choice = room:askForChoice(to, names, self.name, "#kl__wenji-choice:" .. player.id .. "::" .. c:toLogString())
--     -- 让目标角色选择一种名称。
--     room:doBroadcastNotify("ShowToast", Fk:translate("kl__wenji_choice") .. Fk:translate(choice))
--     -- 广播目标角色选择的牌名。
--     room:setCardMark(c, "kl__wenji-inhand", choice)
--     -- 设置卡牌标记为目标角色选择的牌名。
--     room:setCardMark(c, "@kl__wenji-inhand", Fk:translate(choice))
--     -- -- 设置卡牌的翻译标记。
--     -- room:handleAddLoseSkills(player, "-kl__wenji|kl__wenjiVS", nil, false, true)
--     -- 移除当前技能，添加“矫诏VS”技能。
--     room:obtainCard(player.id, card[1], true, fk.ReasonGive)
--   end,
-- }
-- local kl__wenjiVS = fk.CreateViewAsSkill {
--   name = "kl__wenjiVS",    -- 技能名称为“矫诏VS”。
--   pattern = ".",           -- 技能的触发模式为任意牌。
--   mute = true,             -- 静默技能，不播放动画或音效。
--   prompt = "#kl__wenjiVS", -- 技能提示信息。
--   card_filter = function(self, to_select, selected)
--     -- 选择的卡牌过滤条件。
--     return #selected == 0 and Fk:getCardById(to_select):getMark("kl__wenji-inhand") ~= 0
--     -- 只能选择一张手牌，且该手牌必须有“kl__wenji-inhand”标记。
--   end,
--   view_as = function(self, cards)
--     -- 将选中的卡牌视为其他牌。
--     if #cards ~= 1 then return end
--     -- 如果选中的牌数量不是 1，则返回空。
--     local card = Fk:cloneCard(Fk:getCardById(cards[1]):getMark("kl__wenji-inhand"))
--     -- 克隆一张卡牌，将其视为“kl__wenji-inhand”标记对应的牌。
--     card.skillName = "kl__wenji"
--     -- 设置技能名称为“矫诏”。
--     card:addSubcard(cards[1])
--     -- 将选中的卡牌作为子牌附加到克隆的牌上。
--     return card
--   end,
--   before_use = function(self, player, use)
--     -- 在使用牌之前的逻辑。
--     local room = player.room
--     player:broadcastSkillInvoke("kl__wenji")
--     -- 播放技能音效。
--     room:notifySkillInvoked(player, "kl__wenji", "special")
--     -- 通知技能被触发。
--     -- room:handleAddLoseSkills(player, kl__wenjiSkills[player:getMark("kl__wenji_status")].."|-kl__wenjiVS", nil, false, true)
--     -- -- 根据玩家的“kl__wenji_status”标记，更新技能状态。
--   end,
--   enabled_at_play = function(self, player)
--     -- 判断技能是否可以在出牌阶段使用。
--     return table.find(player:getCardIds("h"),
--       function(id) return Fk:getCardById(id):getMark("kl__wenji-inhand") ~= 0 end)
--     -- 如果玩家手牌中存在带有“kl__wenji-inhand”标记的牌，则可以使用。
--   end,
--   enabled_at_response = function(self, player, response)
--     -- 判断技能是否可以在响应阶段使用。
--     return not response and player.phase ~= Player.NotActive and
--         table.find(player:getCardIds("h"),
--           function(id) return Fk:getCardById(id):getMark("kl__wenji-inhand") ~= 0 end)
--     -- 如果当前没有响应模式，且玩家不处于非激活阶段，并且手牌中存在带有“kl__wenji-inhand”标记的牌，则可以使用。
--   end,
-- }
-- local kl__tunjiang = fk.CreateTriggerSkill {
--   name = "kl__tunjiang",
--   anim_type = "drawcard",
--   events = { fk.EventPhaseStart },
--   can_trigger = function(self, event, target, player, data)
--     return target == player and player:hasSkill(self) and player.phase == Player.Finish and
--         player:getMark("kl__tunjiang-turn") == 0
--   end,
--   on_use = function(self, event, target, player, data)
--     local room = player.room
--     local num = 0
--     for _, v in pairs(H.getKingdomPlayersNum(room)) do
--       if v and v > 0 then
--         num = num + 1
--       end
--     end
--     player:drawCards(num, self.name)
--   end,

--   refresh_events = { fk.TargetSpecified },
--   can_refresh = function(self, event, target, player, data)
--     return target == player and player:hasSkill(self) and player.phase == Player.Play and
--         player:getMark("kl__tunjiang-turn") == 0 and
--         data.firstTarget and data.card.type ~= Card.TypeEquip
--   end,
--   on_refresh = function(self, event, target, player, data)
--     if #AimGroup:getAllTargets(data.tos) == 0 then return end
--     for _, id in ipairs(AimGroup:getAllTargets(data.tos)) do
--       if id ~= player.id then
--         player.room:addPlayerMark(player, "kl__tunjiang-turn", 1)
--         break
--       end
--     end
--   end,
-- } ---bug:问计牌没有标记
-- kl__wenjiVS:addRelatedSkill(kl__wenji)
-- liuqi:addSkill(kl__wenjiVS)
-- liuqi:addSkill(kl__tunjiang)
-- Fk:loadTranslationTable {
--   ["kl__liuqi"] = "刘琦",
--   ["#kl__liuqi"] = "居外而安",
--   ["designer:kl__liuqi"] = "官方&抗绿先锋",

--   ["kl__wenjiVS"] = "问计",
--   [":kl__wenjiVS"] = "出牌阶段开始时，你可令一名其他角色声明一种普通锦囊牌名并正面朝上交给你一张牌，本阶段你可将此牌当该锦囊牌使用。",
--   ["kl__tunjiang"] = "屯江",
--   [":kl__tunjiang"] = "结束阶段，若你未跳过本回合的出牌阶段，且你于本回合出牌阶段内未使用牌指定过其他角色为目标，则你可以摸X张牌（X为全场势力数）。",

--   ["kl__wenji_choice:"] = "请声明一种牌名：",
--   ["kl__wenji_choice"] = "问计声明牌名：",
--   ["#kl__wenji-choose"] = "问计：你可令一名其他角色交给你一张牌",
--   ["#kl__wenji-give"] = "问计：你需正面朝上交给 %dest 一张牌",
--   ["@kl__wenji-inhand"] = "问计",
--   ["kl__wenji"] = "问计",
--   ["#kl__wenji"] = "问计",
--   ["#kl__wenjiVS"] = "问计：你可将“问计”牌当本回合被声明的牌使用",

--   ["$kl__wenji1"] = "言出子口，入于吾耳，可以言未？",
--   ["$kl__wenji2"] = "还望先生救我！",
--   ["$kl__tunjiang1"] = "皇叔勿惊，吾与关将军已到。",
--   ["$kl__tunjiang2"] = "江夏冲要之地，孩儿愿往守之。",
--   ["~kl__liuqi"] = "父亲，孩儿来见你了。",
-- }

-- local yuji = General(extension, "kl__yuji", "qun", 3, 3, General.Male)
-- local kl__guhuo = fk.CreateViewAsSkill {
--   name = "kl__guhuo",
--   pattern = ".",
--   interaction = function(self)
--     local all_names = U.getAllCardNames("bt")
--     local names = U.getViewAsCardNames(Self, self.name, all_names)
--     if #names == 0 then return false end
--     return U.CardNameBox { choices = names, all_choices = all_names }
--   end,
--   card_filter = function(self, to_select, selected)
--     return #selected == 0 and Fk:currentRoom():getCardArea(to_select) ~= Card.PlayerEquip
--   end,
--   view_as = function(self, cards)
--     if #cards ~= 1 or not self.interaction.data then return end
--     local card = Fk:cloneCard(self.interaction.data)
--     self.cost_data = cards
--     card.skillName = self.name
--     return card
--   end,
--   before_use = function(self, player, use)
--     local room = player.room
--     local cards = self.cost_data
--     local card_id = cards[1]
--     room:moveCardTo(cards, Card.Void, nil, fk.ReasonPut, self.name, "", false) --暂时放到Card.Void,理论上应该是Card.Processing,只要moveVisible可以false
--     local targets = TargetGroup:getRealTargets(use.tos)
--     if targets and #targets > 0 then
--       room:sendLog {
--         type = "#kl__guhuo_use",
--         from = player.id,
--         to = targets,
--         arg = use.card.name,
--         arg2 = self.name
--       }

--       room:doIndicate(player.id, targets)
--     else
--       room:sendLog {
--         type = "#kl__guhuo_no_target",
--         from = player.id,
--         arg = use.card.name,
--         arg2 = self.name
--       }
--     end

--     local questioned = {}
--     for _, p in ipairs(room:getOtherPlayers(player)) do
--       if p.hp > 0 then
--         local choice = room:askForChoice(p, { "noquestion", "question" }, self.name,
--           "#kl__guhuo-ask::" .. player.id .. ":" .. use.card.name)
--         if choice ~= "noquestion" then
--           table.insertIfNeed(questioned, p)
--         end
--         room:sendLog {
--           type = "#kl__guhuo_query",
--           from = p.id,
--           arg = choice
--         }
--       end
--     end
--     local success = false
--     local canuse = false
--     local kl__guhuo_card = Fk:getCardById(card_id)
--     if #questioned > 0 then
--       if use.card.name == kl__guhuo_card.name then
--         success = true
--         if kl__guhuo_card.suit == Card.Heart or kl__guhuo_card.suit ~= Card.Heart then
--           canuse = true
--         end
--       end
--     else
--       canuse = true
--     end
--     player:showCards({ card_id })
--     --暂时使用setCardArea,当moveVisible可以false之后,不必再移动到Card.Void,也就不必再setCardArea
--     table.removeOne(room.void, card_id)
--     table.insert(room.processing_area, card_id)
--     room:setCardArea(card_id, Card.Processing, nil)
--     --
--     if success then
--       for _, p in ipairs(questioned) do
--         room:loseHp(p, 1, self.name)
--       end
--     else
--       for _, p in ipairs(questioned) do
--         p:drawCards(1, self.name)
--       end
--     end
--     if canuse then
--       use.card:addSubcard(card_id)
--     else
--       room:moveCardTo(card_id, Card.DiscardPile, nil, fk.ReasonPutIntoDiscardPile, self.name)
--       return ""
--     end
--   end,
--   enabled_at_play = function(self, player)
--     return not player:isKongcheng()
--   end,
--   enabled_at_response = function(self, player, response)
--     return not player:isKongcheng()
--   end,
-- }
-- yuji:addSkill(kl__guhuo)
-- Fk:loadTranslationTable {
--   ["kl__yuji"] = "于吉",
--   ["#kl__yuji"] = "太平道人",
--   ["designer:kl__yuji"] = "官方&抗绿先锋",

--   ["kl__guhuo"] = "蛊惑",
--   [":kl__guhuo"] = "你可以扣置一张手牌当做一张基本牌或普通锦囊牌使用或打出，体力值大于0的其他角色选择是否质疑，然后你展示此牌：" ..
--       "若无角色质疑，此牌按你所述继续结算；若有角色质疑：若此牌为真，质疑角色各失去1点体力，否则质疑角色各摸一张牌，" ..
--       "且若此牌为真，则按你所述继续结算，否则将之置入弃牌堆。",
--   ["#kl__guhuo-ask"] = "蛊惑：是否质疑 %dest 使用/打出的 %arg",
--   ["question"] = "质疑",
--   ["noquestion"] = "不质疑",
--   ["#kl__guhuo_use"] = "%from 发动了 “%arg2”，声明此牌为 %arg，指定的目标为 %to",
--   ["#kl__guhuo_no_target"] = "%from 发动了“%arg2”，声明此牌为 %arg",
--   ["#kl__guhuo_query"] = "%from 表示 %arg",

--   ["$kl__guhuo1"] = "你信吗？",
--   ["$kl__guhuo2"] = "猜猜看呐~",
--   ["~kl__yuji"] = "竟然…被猜到了…",
-- }

-- local zuoci = General(extension, "kl__zuoci", "qun", 3)
-- ---@param player ServerPlayer
-- ---@param skillName string
-- local addFangkeSkill = function(player, skillName)
--   local room = player.room
--   local skill = Fk.skills[skillName]
--   if (not skill) or skill.lordSkill or skill.switchSkillName
--       or skill.frequency > 2 or skill.relate_to_place == "m" or skill.relate_to_place == "d"
--       or player:hasSkill(skill) then
--     return
--   end

--   room:addTableMark(player, "kl__xing_skills", skillName)
--   player:addFakeSkill(skill)
--   player:prelightSkill(skill, true)
-- end

-- ---@param player ServerPlayer
-- ---@param skillName string
-- local removeFangkeSkill = function(player, skillName)
--   local room = player.room
--   local skill = Fk.skills[skillName]
--   room:removeTableMark(player, "kl__xing_skills", skillName)
--   player:loseFakeSkill(skill)
-- end

-- ---@param player ServerPlayer
-- ---@param general General
-- ---@param addSkill bool
-- local function addFangke(player, general, addSkill)
--   local room = player.room
--   local glist = player:getMark("@&kl__xing")
--   if glist == 0 then glist = {} end
--   table.insertIfNeed(glist, general.name)
--   room:setPlayerMark(player, "@&kl__xing", glist)

--   if not addSkill then return end
--   for _, s in ipairs(general.skills) do
--     addFangkeSkill(player, s.name)
--   end
--   for _, sname in ipairs(general.other_skills) do
--     addFangkeSkill(player, sname)
--   end
-- end

-- ---@param player ServerPlayer
-- ---@param general string
-- local function removeFangke(player, general)
--   local room = player.room
--   local glist = player:getTableMark("@&kl__xing")
--   if table.removeOne(glist, general) then
--     if #glist == 0 then glist = 0 end
--     room:setPlayerMark(player, "@&kl__xing", glist)
--     for _, sname in ipairs(Fk.generals[general]:getSkillNameList()) do
--       removeFangkeSkill(player, sname)
--     end
--   end
-- end

-- -- local kl__xinsheng = fk.CreateTriggerSkill {
-- --   name = "kl__xinsheng",
-- --   events = { fk.EventPhaseStart, fk.Damaged },
-- --   can_trigger = function(self, event, target, player, _)
-- --     if not (target == player and player:hasSkill(self)) then return end
-- --     return event == fk.Damaged or player.phase == Player.Start
-- --   end,
-- --   on_use = function(self, event, _, player, _)
-- --     local room = player.room
-- --     local generals = {}
-- --     if event == fk.EventPhaseStart then
-- --       local m = player:getMark("@&kl__xing")
-- --       if m == 0 or #m < 2 then
-- --         local all_xing = room:getNGenerals(5)
-- --         local result = room:askForCustomDialog(player, self.name,
-- --           "packages/utility/qml/ChooseGeneralsAndChoiceBox.qml", {
-- --             all_xing,
-- --             { "OK" },
-- --             "#kl__xinshen_xing2",
-- --             {},
-- --             2,
-- --             2
-- --           })
-- --         if result ~= "" then
-- --           local reply = json.decode(result)
-- --           generals = reply.cards
-- --         else
-- --           generals = table.random(all_xing, 2)
-- --         end
-- --       else
-- --         local choices = player:getMark("@&kl__xing")
-- --         local choice
-- --         local result = room:askForCustomDialog(player, self.name,
-- --           "packages/utility/qml/ChooseGeneralsAndChoiceBox.qml", {
-- --             choices,
-- --             { "OK" },
-- --             "#kl__xinshen_xing_recast"
-- --           })
-- --         if result ~= "" then
-- --           local reply = json.decode(result)
-- --           choice = reply.cards[1]
-- --         else
-- --           choice = table.random(choices) ---@type string
-- --         end
-- --         removeFangke(player, choice)
-- --         generals = room:getNGenerals(1)
-- --       end
-- --     else
-- --       generals = room:getNGenerals(1)
-- --     end
-- --     table.forEach(generals, function(g) addFangke(player, Fk.generals[g], true) end)
-- --   end,

-- --   refresh_events = { fk.EventLoseSkill, fk.GeneralHidden, fk.BuryVictim },
-- --   can_refresh = function(self, event, target, player, data)
-- --     if player:getMark("@&kl__xing") == 0 or player ~= target then return false end
-- --     if event == fk.EventLoseSkill then
-- --       return data == self
-- --     elseif event == fk.BuryVictim then
-- --       return true
-- --     elseif event == fk.GeneralHidden then
-- --       return table.contains(Fk.generals[data]:getSkillNameList(), self.name)
-- --     end
-- --   end,
-- --   on_refresh = function(self, event, target, player, data)
-- --     local record = table.simpleClone(player:getMark("@&kl__xing"))
-- --     for _, s in ipairs(record) do
-- --       removeFangke(player, s)
-- --     end
-- --   end,
-- -- }
-- local kl__xinsheng = fk.CreateTriggerSkill {
--   name = "kl__xinsheng",
--   events = { fk.GeneralRevealed },
--   frequency = Skill.Compulsory,
--   can_trigger = function(self, event, target, player, data)
--     if target ~= player and not player:hasSkill(self) then return false end
--     if target == player and player:hasSkill(self) then
--       for _, v in pairs(data) do
--         if table.contains(Fk.generals[v]:getSkillNameList(), self.name) then return true end
--       end
--     end
--     return true
--   end,
--   on_use = function(self, event, _, player, _)
--     local generals = player.room:getNGenerals(1)
--     table.forEach(generals, function(g) addFangke(player, Fk.generals[g], true) end)
--   end,

--   refresh_events = { fk.EventLoseSkill, fk.GeneralHidden, fk.BuryVictim },
--   can_refresh = function(self, event, target, player, data)
--     if player:getMark("@&kl__xing") == 0 or player ~= target then return false end
--     if event == fk.EventLoseSkill then
--       return data == self
--     elseif event == fk.BuryVictim then
--       return true
--     elseif event == fk.GeneralHidden then
--       return table.contains(Fk.generals[data]:getSkillNameList(), self.name)
--     end
--   end,
--   on_refresh = function(self, event, target, player, data)
--     local record = table.simpleClone(player:getMark("@&kl__xing"))
--     for _, s in ipairs(record) do
--       removeFangke(player, s)
--     end
--   end,
-- }
-- local kl__huashen = fk.CreateTriggerSkill {
--   name = "kl__huashen",
--   events = { fk.AfterSkillEffect },
--   can_trigger = function(self, _, target, player, data)
--     return target == player and player:hasSkill(self) and
--         table.contains(player:getTableMark("kl__xing_skills"), data.name) and
--         player:usedSkillTimes(self.name, Player.HistoryTurn) < 1
--   end,
--   on_cost = Util.TrueFunc,
--   on_use = function(self, _, target, player, data)
--     local all_xing = player:getMark("@&kl__xing")
--     local choices = {}
--     for _, s in ipairs(all_xing) do
--       local general = Fk.generals[s]
--       local skills = general:getSkillNameList()
--       if table.contains(skills, data.name) then
--         table.insert(choices, s)
--       end
--     end
--     local choice = player.room:askForChoice(player, choices, self.name, "#kl__huashen_remove")
--     removeFangke(player, choice)
--     local generals = player.room:getNGenerals(1)
--     table.forEach(generals, function(g) addFangke(player, Fk.generals[g], true) end)
--   end,
-- }
-- zuoci:addSkill(kl__xinsheng)
-- zuoci:addSkill(kl__huashen)
-- Fk:loadTranslationTable {
--   ["kl__zuoci"] = "左慈",
--   ["#kl__zuoci"] = "鬼影神道",
--   ["designer:kl__zuoci"] = "官方&抗绿先锋",

--   ["kl__huashen"] = "化身",
--   [":kl__huashen"] = "每回合限一次，你可重铸一张“化身”并发动此牌上的一个无技能标签的技能。",
--   -- ["kl__xinsheng"] = "新生",
--   -- [":kl__xinsheng"] = "准备阶段，若你的“形”：少于两张，你可以观看武将牌堆中的随机五张武将牌，选择其中的两张置于你的武将牌上（称为“形”）；不少于两张，你可以将一张“形”置入武将牌堆，然后随机将武将牌堆中的一张武将牌置于你的武将牌上（称为“形”）。" ..
--   --     "当你受到伤害后，你可以随机将武将牌堆中的一张武将牌置于你的武将牌上（称为“形”）。",
--   ["kl__xinsheng"] = "新生",
--   [":kl__xinsheng"] = "锁定技，当你明置此武将牌后，你在剩余武将牌堆中获得五张牌作为“化身”。",
--   ["@&kl__xing"] = "化身",

--   ["#kl__xinshen_xing1"] = "新生：选择一张武将牌置于你的武将牌上，称为“形”",
--   ["#kl__xinshen_xing2"] = "新生：选择两张武将牌置于你的武将牌上，称为“形”",
--   ["#kl__xinshen_xing_recast"] = "新生：移去一张“形”，然后随机将一张武将牌置于你的武将牌上，称为“形”",
--   ["#kl__huashen_remove"] = "化身：移去一张“形”",

--   ["$kl__huashen1"] = "哼，肉眼凡胎，岂能窥视仙人变幻？",
--   ["$kl__huashen2"] = "万物苍生，幻化由心。",
--   ["$kl__xinsheng1"] = "幻幻无穷，生生不息。",
--   ["$kl__xinsheng2"] = "吐故纳新，师法天地。",
--   ["~kl__zuoci"] = "腾云跨风，飞升太虚……",
-- }
-- ---@param player ServerPlayer
-- ---@param skillName string
-- local addFangkeSkill = function(player, skillName)
--   local room = player.room
--   local skill = Fk.skills[skillName]
--   if (not skill) or skill.lordSkill or skill.switchSkillName
--       or skill.frequency > 2 or skill.relate_to_place == "m" or skill.relate_to_place == "d"
--       or player:hasSkill(skill) then
--     return
--   end

--   room:addTableMark(player, "ld__n_xing_skills", skillName)
--   player:addFakeSkill(skill)
--   player:prelightSkill(skill, true)
-- end

-- ---@param player ServerPlayer
-- ---@param skillName string
-- local removeFangkeSkill = function(player, skillName)
--   local room = player.room
--   local skill = Fk.skills[skillName]
--   room:removeTableMark(player, "ld__n_xing_skills", skillName)
--   player:loseFakeSkill(skill)
-- end

-- ---@param player ServerPlayer
-- ---@param general General
-- ---@param addSkill bool
-- local function addFangke(player, general, addSkill)
--   local room = player.room
--   local glist = player:getMark("@&ld__n_xing")
--   if glist == 0 then glist = {} end
--   table.insertIfNeed(glist, general.name)
--   room:setPlayerMark(player, "@&ld__n_xing", glist)

--   if not addSkill then return end
--   for _, s in ipairs(general.skills) do
--     addFangkeSkill(player, s.name)
--   end
--   for _, sname in ipairs(general.other_skills) do
--     addFangkeSkill(player, sname)
--   end
-- end

-- ---@param player ServerPlayer
-- ---@param general string
-- local function removeFangke(player, general)
--   local room = player.room
--   local glist = player:getTableMark("@&ld__n_xing")
--   if table.removeOne(glist, general) then
--     if #glist == 0 then glist = 0 end
--     room:setPlayerMark(player, "@&ld__n_xing", glist)
--     for _, sname in ipairs(Fk.generals[general]:getSkillNameList()) do
--       removeFangkeSkill(player, sname)
--     end
--   end
-- end

-- -----
-- local zuoci = General(extension, "ld__n_zuoci", "qun", 3)
-- zuoci:addCompanions("ld__n_yuji")
-- local xinsheng = fk.CreateTriggerSkill {
--   name = "ld__n_xinsheng",
--   events = { fk.EventPhaseStart, fk.Damaged },
--   can_trigger = function(self, event, target, player, _)
--     if not (target == player and player:hasSkill(self)) then return end
--     return event == fk.Damaged or player.phase == Player.Start
--   end,
--   on_use = function(self, event, _, player, _)
--     local room = player.room
--     local generals = {}
--     if event == fk.EventPhaseStart then
--       local m = player:getMark("@&ld__n_xing")
--       if m == 0 or #m < 2 then
--         local all_xing = room:getNGenerals(5)
--         local result = room:askForCustomDialog(player, self.name,
--           "packages/utility/qml/ChooseGeneralsAndChoiceBox.qml", {
--             all_xing,
--             { "OK" },
--             "#ld__n_xinshen_xing2",
--             {},
--             2,
--             2
--           })
--         if result ~= "" then
--           local reply = json.decode(result)
--           generals = reply.cards
--         else
--           generals = table.random(all_xing, 2)
--         end
--       else
--         local choices = player:getMark("@&ld__n_xing")
--         local choice
--         local result = room:askForCustomDialog(player, self.name,
--           "packages/utility/qml/ChooseGeneralsAndChoiceBox.qml", {
--             choices,
--             { "OK" },
--             "#ld__n_xinshen_xing_recast"
--           })
--         if result ~= "" then
--           local reply = json.decode(result)
--           choice = reply.cards[1]
--         else
--           choice = table.random(choices) ---@type string
--         end
--         removeFangke(player, choice)
--         generals = room:getNGenerals(1)
--       end
--     else
--       generals = room:getNGenerals(1)
--     end
--     table.forEach(generals, function(g) addFangke(player, Fk.generals[g], true) end)
--   end,

--   refresh_events = { fk.EventLoseSkill, fk.GeneralHidden, fk.BuryVictim },
--   can_refresh = function(self, event, target, player, data)
--     if player:getMark("@&ld__n_xing") == 0 or player ~= target then return false end
--     if event == fk.EventLoseSkill then
--       return data == self
--     elseif event == fk.BuryVictim then
--       return true
--     elseif event == fk.GeneralHidden then
--       return table.contains(Fk.generals[data]:getSkillNameList(), self.name)
--     end
--   end,
--   on_refresh = function(self, event, target, player, data)
--     local record = table.simpleClone(player:getMark("@&ld__n_xing"))
--     for _, s in ipairs(record) do
--       removeFangke(player, s)
--     end
--   end,
-- }
-- local huashen = fk.CreateTriggerSkill {
--   name = "ld__n_huashen",
--   events = { fk.AfterSkillEffect },
--   can_trigger = function(self, _, target, player, data)
--     return target == player and player:hasSkill(self) and
--         table.contains(player:getTableMark("ld__n_xing_skills"), data.name)
--   end,
--   on_cost = Util.TrueFunc,
--   on_use = function(self, _, target, player, data)
--     local all_xing = player:getMark("@&ld__n_xing")
--     local choices = {}
--     for _, s in ipairs(all_xing) do
--       local general = Fk.generals[s]
--       local skills = general:getSkillNameList()
--       if table.contains(skills, data.name) then
--         table.insert(choices, s)
--       end
--     end
--     local choice = player.room:askForChoice(player, choices, self.name, "#ld__n_huashen_remove")
--     removeFangke(player, choice)
--     generals = room:getNGenerals(1)
--   end,
-- }
-- zuoci:addSkill(xinsheng)
-- zuoci:addSkill(huashen)
-- Fk:loadTranslationTable {
--   ["ld__n_zuoci"] = "左慈",
--   ["#ld__n_zuoci"] = "鬼影神道",

--   ["ld__n_huashen"] = "化身",
--   [":ld__n_huashen"] = "当你需要发动“形”拥有的技能时，你可以于对应的时机发动“形”拥有的一个无技能标签的技能，然后于此技能结算后将拥有此技能的“形”置入武将牌堆。<br><font color = 'grey'>注：不要报有关左慈的任何技能触发bug，有极小可能性导致游戏崩溃的除外。</font>",
--   ["ld__n_xinsheng"] = "新生",
--   [":ld__n_xinsheng"] = "准备阶段，若你的“形”：少于两张，你可以观看武将牌堆中的随机五张武将牌，选择其中的两张置于你的武将牌上（称为“形”）；不少于两张，你可以将一张“形”置入武将牌堆，然后随机将武将牌堆中的一张武将牌置于你的武将牌上（称为“形”）。" ..
--       "当你受到伤害后，你可以随机将武将牌堆中的一张武将牌置于你的武将牌上（称为“形”）。",
--   ["@&ld__n_xing"] = "形",
--   ["#ld__n_xinshen_xing1"] = "新生：选择一张武将牌置于你的武将牌上，称为“形”",
--   ["#ld__n_xinshen_xing2"] = "新生：选择两张武将牌置于你的武将牌上，称为“形”",
--   ["#ld__n_xinshen_xing_recast"] = "新生：移去一张“形”，然后随机将一张武将牌置于你的武将牌上，称为“形”",
--   ["#ld__n_huashen_remove"] = "化身：移去一张“形”",

--   ["$ld__n_huashen1"] = "世间万物，贫道皆可化为其形。",
--   ["$ld__n_huashen2"] = "尘身土塑，唯魂魄难得。",
--   ["$ld__n_xinsheng1"] = "大成若缺，损益无妨。",
--   ["$ld__n_xinsheng2"] = "大盈若冲，心神自现。",
--   ["~ld__n_zuoci"] = "仙人之逝，魂归九天…",
-- }
-- local zhanglu = General(extension, "kl__zhanglu", "qun", 3)
-- local kl__mijiao = fk.CreateTriggerSkill {
--   name = "kl__mijiao",
--   attached_skill_name = "kl__mijiao&",
-- }
-- local kl__mijiao_active = fk.CreateActiveSkill {
--   name = "kl__mijiao&",
--   anim_type = "support",
--   target_num = 1,
--   prompt = "#kl__mijiao&",
--   can_use = function(self, player)
--     local targetRecorded = player:getTableMark("kl__mijiao_targets-phase")
--     return table.find(Fk:currentRoom().alive_players, function(p)
--       return p ~= player and p:hasSkill(kl__mijiao, true) and not table.contains(targetRecorded, p.id)
--     end)
--   end,
--   card_filter = function(self, to_select, selected)
--     return table.contains(Self:getCardIds("he"), to_select)
--   end,
--   target_filter = function(self, to_select, selected)
--     return #selected == 0 and to_select ~= Self.id and Fk:currentRoom():getPlayerById(to_select):hasSkill(kl__mijiao) and
--         not table.contains(Self:getTableMark("kl__mijiao_targets-phase"), to_select)
--   end,
--   on_use = function(self, room, effect)
--     local player = room:getPlayerById(effect.from)
--     local target = room:getPlayerById(effect.tos[1])
--     target:broadcastSkillInvoke("kl__mijiao")
--     room:addTableMarkIfNeed(player, "kl__mijiao_targets-phase", target.id)
--     local id = effect.cards
--     room:obtainCard(target.id, id, false, fk.ReasonGive, player.id)
--     print("Length of id:", #id) -- 在这里打印 id 的长度
--     print("id:", id)            -- 打印 id 的内容
--     if #id > 1 and not player.dead and player:isWounded() then
--       if room:askForSkillInvoke(target, self.name, nil, "#kl__mijiao-recover::" .. player.id) then
--         room:recover({
--           who = player,
--           num = 1,
--           recoverBy = target,
--           skillName = self.name,
--         })
--       end
--     end
--   end,
-- }
-- local kl__yishe = fk.CreateViewAsSkill {
--   name = "kl__yishe",
--   anim_type = "offensive",
--   pattern = "amazing_grace",
--   prompt = "#kl__yishe",
--   handly_pile = true,
--   card_filter = function(self, to_select, selected, player)
--     local alive_count = #Fk:currentRoom().alive_players
--     return #selected < alive_count
--   end,
--   view_as = function(self, cards)
--     local c = Fk:cloneCard("amazing_grace")
--     c.skillName = self.name
--     c:addSubcards(cards)
--     return c
--   end,
--   before_use = function(self, player, useData)
--     useData.extra_data = useData.extra_data or {}
--     useData.extra_data.kl__yisheUser = player.id
--   end,
--   enabled_at_play = function(self, player)
--     return player:usedSkillTimes(self.name, Player.HistoryPhase) < 1
--   end,
--   enabled_at_response = Util.FalseFunc,
-- }
-- local kl__yishe__target = fk.CreateTriggerSkill {
--   name = "#kl__yishe__target",
--   anim_type = "offensive",
--   events = { fk.TargetSpecified },
--   can_trigger = function(self, event, target, player, data)
--     if player:hasSkill(self) and
--         (event == fk.TargetSpecified and data.firstTarget) and
--         -- table.find(AimGroup:getAllTargets(data.tos), function(id)
--         --   return not player.room:getPlayerById(id).dead
--         -- end)
--         target == player
--     then
--       local e = player.room.logic:getCurrentEvent():findParent(GameEvent.UseCard)
--       if e then
--         local use = e.data[1]
--         if use.card.trueName == "amazing_grace" and use.extra_data and use.extra_data.kl__yishe then
--           return true
--         end
--       end
--     end
--   end,
--   on_cost = function(self, event, target, player, data)
--     local tos = player.room:askForChoosePlayers(player, AimGroup:getAllTargets(data.tos),
--       1, 999, "#kl__yishe__target-choose:::" .. data.card:toLogString(), self.name, true)
--     if #tos > 0 then
--       self.cost_data = { tos = tos }
--       return true
--     end
--   end,
--   on_use = function(self, event, target, player, data)
--     table.insertTableIfNeed(data.nullifiedTargets, self.cost_data.tos)
--   end,
-- }
-- zhanglu:addSkill(kl__yishe)
-- zhanglu:addSkill(kl__mijiao)
-- kl__mijiao:addRelatedSkill(kl__mijiao_active)
-- kl__yishe:addRelatedSkill(kl__yishe__target)
-- Fk:loadTranslationTable {
--   ["kl__zhanglu"] = "张鲁",
--   ["#kl__zhanglu"] = "政宽教惠",
--   ["designer:kl__zhanglu"] = "抗绿先锋&土豆",

--   ["kl__mijiao"] = "米教",
--   ["kl__mijiao&"] = "米教",
--   [":kl__mijiao"] = "其他角色出牌阶段限一次，其可交给你至少一张牌。若此次给出的牌数大于一，你可令其回复1点体力。",
--   ["#kl__mijiao&"] = "米教：你可交给其至少一张牌。若此次给出的牌数大于一，其可令你回复1点体力。",
--   ["#kl__mijiao-recover::"] = "米教：是否令%dest回复1点体力？",
--   ["kl__yishe"] = "义舍",
--   [":kl__yishe"] = "出牌阶段限一次，你可将至少一张牌当仅对等量名角色生效的【五谷丰登】使用。目标角色可额外获得一张牌，然后受到1点伤害。",

--   ["$kl__yishe1"] = "行大义之举，须有向道之心。",
--   ["$kl__yishe2"] = "你有你的权谋，我，哼，自有我的道义。",
--   ["$kl__mijiao1"] = "从善从良，从五斗米道。",
--   ["$kl__mijiao2"] = "兼济天下，解百姓之忧。",
--   ["~kl__zhanglu"] = "但，归置于道，无意凡事争斗。",
-- }
-- local chendeng = General(extension, "kl__chendeng", "qun", 3, 3, General.Male)
-- local kl__zhouxuan = fk.CreateViewAsSkill {
--   name = "kl__zhouxuan",
--   anim_type = "defensive",
--   pattern = "slash,jink",
--   prompt = "#kl__zhouxuan",
--   interaction = function()
--     local names = {}
--     for _, name in ipairs({ "slash", "jink" }) do
--       local card = Fk:cloneCard(name)
--       if (Fk.currentResponsePattern == nil and Self:canUse(card)) or
--           (Fk.currentResponsePattern and Exppattern:Parse(Fk.currentResponsePattern):match(card)) then
--         table.insertIfNeed(names, card.name)
--       end
--     end
--     if #names == 0 then return end
--     return U.CardNameBox { choices = names }
--   end,
--   card_filter = Util.FalseFunc,
--   view_as = function(self)
--     if not self.interaction.data then return end
--     local card = Fk:cloneCard(self.interaction.data)
--     card.skillName = self.name
--     return card
--   end,
--   before_use = function(self, player, use)
--     local room = player.room
--     local current = room.current
--     local id = room:askForCard(player, 1, 1, true, self.name, false, ".", "#kl__yingtu-choose::" .. current.id)[1]
--     player:showCards(id)
--     local card = Fk:getCardById(id)
--     if current:canUse(card) then
--       room:askForUseRealCard(current, { id }, self.name, "#kl__zhouxuan-use", { bypass_times = true }, false)
--     else
--       room:obtainCard(current, card, true, fk.ReasonPrey)
--     end
--   end,
--   enabled_at_play = function(self, player)
--     return
--         not player:isNude()
--   end,
--   enabled_at_response = function(self, player, res)
--     return
--         not player:isNude()
--   end,
-- } --bug:回合内展示装备区内的牌或回合外周旋展示牌后，当前回合角色既不使用又不获得
-- local kl__guitu = fk.CreateActiveSkill {
--   name = "kl__guitu",
--   anim_type = "offensive",
--   prompt = "#kl__guitu",
--   can_use = function(self, player)
--     return player:usedSkillTimes(self.name, Player.HistoryPhase) < 2 and Self.phase == Player.Play
--   end,
--   card_filter = function(self, to_select, selected)
--     if #selected == 1 then return false end
--     local card = Fk:getCardById(to_select)
--     return card.color == Card.Black
--   end,
--   target_filter = function(self, to_select, selected)
--     return #selected == 0
--   end,
--   target_num = 1,
--   on_use = function(self, room, effect)
--     local player = room:getPlayerById(effect.from)
--     local target = room:getPlayerById(effect.tos[1])
--     room:useVirtualCard("collateral", effect.cards, player, target, self.name, true)
--   end,
-- } --bug:使用后没有任何反应
-- chendeng:addSkill(kl__zhouxuan)
-- chendeng:addSkill(kl__guitu)
-- Fk:loadTranslationTable {
--   ["kl__chendeng"] = "陈登",
--   ["#kl__chendeng"] = "惊涛弄潮",
--   ["designer:kl__chendeng"] = "抗绿先锋",

--   ["kl__guitu"] = "诡图",
--   ["#kl__guitu"] = "诡图：你可将一张黑色牌当【借刀杀人】使用（目标可不合法）。",
--   [":kl__guitu"] = "你可将一张黑色牌当【借刀杀人】使用（目标可不合法）。",
--   ["kl__zhouxuan"] = "周旋",
--   [":kl__zhouxuan"] = "每回合限一次，当你需要使用或打出【杀】或【闪】时，你可展示一张牌，令当前回合角色使用之（不可使用则获得之），然后视为你使用或打出一张【杀】或【闪】。",
--   ["#Error1"] = "无id",
--   ["#Error2"] = "无card",
--   ["$kl__zhouxuan1"] = "今日，怕是要辜负温侯美意了。",
--   ["$kl__zhouxuan2"] = "前盖以惑敌，今图穷而匕见。",
--   ["$kl__guitu1"] = "孰为虎？孰为鹰？于吾都如棋子。",
--   ["$kl__guitu2"] = "群雄逐鹿之际，唯有洞明时势方有所成。",
--   ["~kl__chendeng"] = "诸卿何患无令君乎？",
-- }
-- local caifuren = General(extension, "kl__caifuren", "qun", 3, 3, General.Female)
return extension
